home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / ghostscript / 8.64 / Resource / Init / gs_cff.ps < prev    next >
Encoding:
Text File  |  2009-04-17  |  24.0 KB  |  857 lines

  1. %    Copyright (C) 1997, 1998, 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: gs_cff.ps 9351 2009-01-13 22:17:21Z alexcher $
  14. % Loader for CFF (compressed) fonts, including OpenType CFFs.
  15. % The following are not implemented yet:
  16. %    Deleted entries in the Name Index
  17. %    Embedded PostScript
  18. %    Multiple Master fonts
  19. %    Chameleon fonts
  20. %    Synthetic fonts
  21.  
  22. % ---------------- Font loading machinery ---------------- %
  23.  
  24. % Augment the FONTPATH machinery so it recognizes OpenType CFF font sets.
  25.  
  26. /.scanfontheaders where {
  27.   pop /.scanfontheaders [
  28.    .scanfontheaders aload pop (OTTO*)
  29.   ] def
  30. } if
  31.  
  32. % Load a font file that might be an OpenType CFF font set.
  33.  
  34. % <file> .loadfontfile -
  35. /.loadnonottofontfile /.loadfontfile load def
  36. /.loadfontfile {
  37.   dup 4 string .peekstring pop (OTTO) eq {
  38.         % If this is a font at all, it's an OpenType CFF font set.
  39.     .init_otto_font_file
  40.     % Use a random FontSet resource name.  ****** WRONG ******
  41.     realtime rand xor =string cvs exch //false //false
  42.     ReadData pop
  43.   } {
  44.         % Not a TrueType font.
  45.     .loadnonottofontfile
  46.   } ifelse
  47. } bind def
  48.  
  49. % <file> .init_otto_font_file <file>
  50. /.init_otto_font_file {
  51.   /FontSetInit /ProcSet findresource begin
  52.   2 dict begin
  53.   /f exch def /cff null def
  54.   card32 pop card16 6 { next pop } repeat dup {
  55.         % Stack: numtables tablesleft
  56.     dup 0 eq {
  57.       pop pop /.loadottofontfile cvx /invalidfont signalerror
  58.     } if
  59.     f 4 string readstring pop (CFF ) eq { sub exit } if
  60.     f 12 string readstring pop pop 1 sub    % skip to next table
  61.   } loop
  62.         % Stack: tablesread
  63.   card32 pop card32 card32
  64.         % Stack: tablesread start length
  65.   exch 3 -1 roll 1 add 16 mul 12 add sub
  66.   f exch subfilefilter flushfile    % skip to start
  67.   f exch subfilefilter end
  68. } bind def
  69.  
  70. 53 dict begin
  71.  
  72. % ---------------- Standard strings (actually names) ---------------- %
  73.  
  74. /StandardStrings mark
  75.     % The initial StandardStrings that that denote characters are
  76.     % defined as a pseudo-Encoding.
  77. % 0
  78.   /CFFStandardStrings .findencoding aload pop
  79. % 379
  80.   (001.000)
  81. % 380
  82.   (001.001) (001.002) (001.003) /Black /Bold
  83.   /Book /Light /Medium /Regular /Roman
  84.   /Semibold
  85. .packtomark def
  86.  
  87. % ---------------- Standard encodings ---------------- %
  88.  
  89. /StandardEncodings [
  90.  
  91. % StandardEncoding
  92. mark
  93.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  94.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  95.   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  96.   17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
  97.   33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
  98.   49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
  99.   65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
  100.   81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 0
  101.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  102.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  103.   0 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
  104.   0 111 112 113 114 0 115 116 117 118 119 120 121 122 0 123
  105.   0 124 125 126 127 128 129 130 131 0 132 133 0 134 135 136
  106.   137 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  107.   0 138 0 139 0 0 0 0 140 141 142 143 0 0 0 0
  108.   0 144 0 0 0 145 0 0 146 147 148 149 0 0 0 0
  109. .packtomark
  110.  
  111. % ExpertEncoding
  112. mark
  113.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  114.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  115.   1 229 230 0 231 232 233 234 235 236 237 238 13 14 15 99
  116.   239 240 241 242 243 244 245 246 247 248 27 28 249 250 251 252
  117.   0 253 254 255 256 257 0 0 0 258 0 0 259 260 261 262
  118.   0 0 263 264 265 0 266 109 110 267 268 269 0 270 271 272
  119.   273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
  120.   289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 0
  121.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  122.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  123.   0 304 305 306 0 0 307 308 309 310 311 0 312 0 0 313
  124.   0 0 314 315 0 0 316 317 318 0 0 0 158 155 163 319
  125.   320 321 322 323 324 325 0 0 326 150 164 169 327 328 329 330
  126.   331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
  127.   347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
  128.   363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
  129. .packtomark
  130.  
  131. ] readonly def
  132.  
  133. % ---------------- Standard Charsets ---------------- %
  134.  
  135. % We include an explicit 0 at the beginning of each charset.
  136.  
  137. /StandardCharsets [
  138.  
  139. % ISOAdobe
  140. mark
  141.   0
  142.   1 1 228 { } for
  143. .packtomark
  144.  
  145. % Expert
  146. mark
  147.   0
  148.   1 229 230 231 232 233 234 235 236 237 238 13 14 15 99 239
  149.   240 241 242 243 244 245 246 247 248 27 28 249 250 251 252 253
  150.   254 255 256 257 258 259 260 261 262 263 264 265 266 109 110 267
  151.   268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
  152.   284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
  153.   300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
  154.   316 317 318 158 155 163 319 320 321 322 323 324 325 326 150 164
  155.   169 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
  156.   342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
  157.   358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
  158.   374 375 376 377 378
  159. .packtomark
  160.  
  161. % ExpertSubset
  162. mark
  163.   0
  164.   1 231 232 235 236 237 238 13 14 15 99 239 240 241 242 243
  165.   244 245 246 247 248 27 28 249 250 251 253 254 255 256 257 258
  166.   259 260 261 262 263 264 265 266 109 110 267 268 269 270 272 300
  167.   301 302 305 314 315 158 155 163 320 321 322 323 324 325 326 150
  168.   164 169 327 328 329 330 331 332 333 334 335 336 337 338 339 340
  169.   341 342 343 344 345 346
  170. .packtomark
  171.  
  172. ] readonly def
  173.  
  174. % ---------------- Font loading ---------------- %
  175.  
  176. % ------ Utilities ------ %
  177.  
  178. /advance {    % <n> advance -
  179.   f cff eq { pos add /pos exch store } { pop } ifelse
  180. } bind def
  181. /next {        % - next <byte>
  182.   f read {
  183.     1 advance
  184.     CFFDEBUG { (  ) print dup = } if
  185.   } {
  186.     0
  187.     CFFDEBUG { (  Out of range access, assuming 0) = } if
  188.     /pdfformaterror where {
  189.       pop 
  190.       (   **** Warning: Out of range access to a CFF table, assuming 0.\n)
  191.       pdfformaterror
  192.     } if
  193.   } ifelse
  194. } bind def
  195. /next2 {    % - next2 <byte1> <byte2>
  196.   f read {
  197.     f read {
  198.       2 advance
  199.       CFFDEBUG { (  ) print 1 index =only (,) print dup = } if
  200.     } {
  201.       1 advance
  202.       CFFDEBUG { (  ) print dup = } if
  203.     } ifelse
  204.   } if
  205. } bind def
  206. /nextstring {    % <length> nextstring <string>
  207.   dup 0 eq {
  208.     pop ()
  209.   } {
  210.     string f exch readstring pop dup length advance
  211.     CFFDEBUG { (  ) print dup == } if
  212.   } ifelse
  213. } bind def
  214. /card8        % - card8 <card8>
  215.  /next load
  216. def
  217. /card16 {    % - card16 <card16>
  218.   next2 exch 8 bitshift add
  219. } bind def
  220. /card32 {    % - card32 <card32>
  221.   card16 16 bitshift card16 add
  222. } bind def
  223. /offsetprocs [
  224.   /card8 load
  225.   /card16 load
  226.   { card8 16 bitshift card16 add } bind
  227.   /card32 load
  228. ] readonly def
  229. /offsetproc {    % <offsize> offsetproc <proc>
  230.   1 sub //offsetprocs exch get
  231. } bind def
  232. /offset {    % <offsize> offset <offset>
  233.   offsetproc exec
  234. } bind def
  235. /sid        % - <sid> sid
  236.   /card16 load
  237. def
  238. /Index {    % <name> Index <name> <array>
  239.   CFFDEBUG { (% reading Index: ) print dup = } if
  240.   mark card16
  241.   dup 0 ne {
  242.     1 exch next
  243.     dup 0 eq { 
  244.       pop       % skip incorrect index, bug 689854
  245.     } {
  246.       offsetproc dup exec pop exch {
  247.         dup exec dup 4 -1 roll sub 3 1 roll exch
  248.       } repeat
  249.     } ifelse pop
  250.   } if pop .packtomark
  251.   CFFDEBUG { (% Index lengths = ) print dup === } if
  252.   [ exch { nextstring } forall ] readonly
  253. } bind def
  254. /tokens {    % - tokens <num1> ... <op#> (op# = 12 means EOF)
  255.   {
  256.     f read not { 12 exit } if
  257.     CFFDEBUG { (..) print dup = } if
  258.     1 advance
  259.     dup 12 eq { pop next 32 add exit } if
  260.     dup 28 lt { exit } if
  261.     dup 32 lt {
  262.       28 sub {
  263.     { card16 32768 xor 32768 sub }
  264.     { 4 offset dup 16#7fffffff gt { -1 32 bitshift add } if }
  265.     { tokenreal }
  266.     { 31 exit }
  267.       } exch get exec
  268.     } {
  269.       dup 247 lt {
  270.     139 sub
  271.       } {
  272.     247 sub {
  273.       { next 108 add }
  274.       { next 364 add }
  275.       { next 620 add }
  276.       { next 876 add }
  277.       { next 108 add neg }
  278.       { next 364 add neg }
  279.       { next 620 add neg }
  280.       { next 876 add neg }
  281.       % 255 is deliberately omitted and will cause a rangecheck
  282.     } exch get exec
  283.       } ifelse
  284.     } ifelse
  285.   } loop
  286. } bind def
  287. /tokenbuf 100 string def
  288. /tokenput {    % <index> <str> tokenput <index+length>
  289.   dup length 3 1 roll
  290.   tokenbuf 2 index 3 -1 roll putinterval add
  291. } bind def
  292. /tokenrealarray [
  293.  (0)(1)(2)(3)(4)(5)(6)(7)(8)(9)(.)(E)
  294.  (E-)
  295.  ()        % ignore the invalid value
  296.  (-)
  297.  { exit } bind
  298. ] readonly def
  299. /tokenreal {    % - tokenreal <float>
  300.   0 {
  301.     next exch 1 index -4 bitshift tokenrealarray exch get exec tokenput
  302.         % We must leave the byte on the stack temporarily so that
  303.         % the exit will see a consistent stack state.
  304.     1 index 15 and tokenrealarray exch get exec tokenput exch pop
  305.   } loop
  306.   tokenbuf 0 3 -1 roll getinterval cvr exch pop
  307. } bind def
  308. /Dict {        % <opsdict> Dict -
  309.   /opdict exch store {
  310.     mark tokens
  311.     CFFDEBUG { (tokens: ) print ] dup === mark exch aload pop } if
  312.     opdict exch .knownget { exec } if cleartomark
  313.   } loop cleartomark
  314. } bind def
  315. /idstring {    % <sid> idstring <string|name>
  316.   dup 391 lt { //StandardStrings } { 391 sub strings } ifelse exch get
  317. } bind def
  318. /idname {    % <sid> idname <name>
  319.   idstring dup type /nametype ne { cvn } if
  320. } bind def
  321. /subfilefilter {    % <file> <length> subfilefilter <filter>
  322.     % SubFileDecode interprets a length of 0 as infinite.
  323.   dup 0 le { pop pop () 0 } if () /SubFileDecode filter
  324. } bind def
  325.  
  326. % ------ Top dictionary ------ %
  327.  
  328. /offput {    % <offset> <proc> offput -
  329.   1 index 0 le
  330.   CFFDEBUG { dup { (not ) print } if (queued: ) print 2 index =only ( ) print 1 index === } if
  331.   { pop pop
  332.   }
  333.   { currentdict exch aload length 1 add packedarray cvx
  334.       offsets 3 1 roll put
  335.   }
  336.   ifelse
  337. } bind def
  338. /queueput {    % <font> <proc> queueput -
  339.   16#7fffffff offsets { pop .min } forall
  340.   pos sub nextstring
  341.   3 1 roll aload length 2 add packedarray cvx
  342.   [ queued aload pop counttomark 2 add -1 roll ]
  343.   /queued exch store
  344. } bind def
  345. /printvk {    % <value> <key> printvk <value> <key>
  346.   CFFDEBUG { (\t% ) print dup =only ( = ) print 1 index === } if
  347. } bind def
  348. /xxput {    % <value> <key> <dict> xxput -
  349.   3 1 roll exch put
  350. } bind def
  351. /putfi {    % <value> <key> putfi -
  352.   printvk FontInfo xxput
  353. } bind def
  354. /xdef {        % <value> <key> xdef -
  355.   exch def
  356. } bind def
  357. /pxdef {    % <value> <key> pxdef -
  358.   printvk xdef
  359. } bind def
  360. /topdictops mark
  361.   12 { CFFDEBUG { (\t% EOD) = } if exit }
  362.   0 { idstring /version putfi }
  363.   1 { idstring /Notice putfi }
  364.   32 { idstring /Copyright putfi }
  365.   2 { idstring /FullName putfi }
  366.   3 { idstring /FamilyName putfi }
  367.   4 { idstring /Weight putfi }
  368.   33 { 0 ne /isFixedPitch putfi }
  369.   34 { /ItalicAngle putfi }
  370.   35 { /UnderlinePosition putfi }
  371.   36 { /UnderlineThickness putfi }
  372.   37 { /PaintType pxdef }
  373.   38 { /FontType pxdef }        % actually CharstringType
  374.   39 { counttomark array astore /FontMatrix pxdef }
  375.   13 { /UniqueID pxdef }
  376.   5 { counttomark array astore /FontBBox pxdef }
  377.   40 { /StrokeWidth pxdef }
  378.   14 { counttomark array astore /XUID pxdef }
  379.   15 {
  380.     /charset printvk pop
  381.     dup StandardCharsets length lt {
  382.       StandardCharsets exch get /charset xdef
  383.     } {
  384.       { queuecharset } offput
  385.     } ifelse
  386.   }
  387.   16 {
  388.     /Encoding printvk pop
  389.     dup StandardEncodings length lt {
  390.       /Encoding xdef
  391.     } {
  392.       { queueEncoding } offput
  393.     } ifelse
  394.   }
  395.   17 { { readCharStrings } offput }
  396.   18 { exch /readPrivate cvx 2 packedarray offput }
  397.     % CIDFont operators
  398.   62 {        % ROS, must be first in a CIDFont
  399.     currentdict /FontType undef
  400.     currentdict /Encoding undef
  401.     currentdict /FontMatrix undef
  402.     /CIDFontVersion 0 def
  403.     /CIDFontRevision 0 def
  404.     /CIDFontType 0 def
  405.     /CIDCount 8720 def % Default value defined in CFF spec.
  406.     3 dict begin
  407.     /Supplement pxdef
  408.     idstring dup type /nametype eq { .namestring } if /Ordering pxdef
  409.     idstring dup type /nametype eq { .namestring } if /Registry pxdef
  410.     /CIDSystemInfo currentdict end def
  411.   }
  412.   63 { /CIDFontVersion pxdef }
  413.   64 { /CIDFontRevision pxdef }
  414.   65 { /CIDFontType pxdef }
  415.   66 { /CIDCount pxdef }
  416.   67 { /UIDBase pxdef }
  417.   68 { { readFDArray } offput }
  418.   69 { { readFDSelect } offput }
  419.     % This operator only appears in a FDArray element.
  420.     % We don't really need it, so ignore an error.
  421.   70 { { idstring } .internalstopped { pop pop } { /FontName pxdef } ifelse }
  422. .dicttomark readonly def
  423.  
  424. % readcharset and readFDSelect may require the length of CharStringArray,
  425. % but these structures may occur in the file before the CharStrings.
  426. % If that happens, use a hack: assume that all the data up to the next
  427. % queued read should be read.
  428.  
  429. /charstringcount {    % <font> charstringcount <count> true
  430.             % <font> charstringcount <length> false
  431.   /CharStringArray .knownget {
  432.     length true
  433.   } {
  434.     % Hack: look for the next queued read.
  435.     16#7fffffff offsets { pop .min } forall
  436.     pos sub false
  437.   } ifelse
  438. } bind def
  439.  
  440. /readCharStrings {    % <font> readCharStrings -
  441.   /CharStringArray Index put
  442. } bind def
  443.  
  444. % ------ Charsets and encodings ------ %
  445.  
  446. % Note: formats 1 and 2 can overflow the operand stack.
  447. % We'll fix this if it ever becomes necessary.
  448. /charsetcount {
  449.   charstringcount { 1 sub } { 2 idiv } ifelse
  450. } bind def
  451. /charsetformats [
  452. { [ 0 3 -1 roll charsetcount { sid } repeat ]
  453. } bind
  454. { [ 0 3 -1 roll charsetcount {
  455.     dup 0 eq { pop exit } if
  456.     sid card8 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
  457.   } loop ]
  458. } bind
  459. { [ 0 3 -1 roll charsetcount {
  460.     dup 0 eq { pop exit } if
  461.     sid card16 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
  462.   } loop ]
  463. } bind
  464. ] readonly def
  465. /queuecharset {        % <font> queuecharset -
  466.   { readcharset } queueput
  467. } bind def
  468. /readcharset {        % <data> <font> readcharset -
  469.   begin 0 () /SubFileDecode filter /f exch store
  470.   charsetformats next get currentdict exch exec /charset exch def end
  471. } bind def
  472.  
  473. /encodingformats [
  474. { 1 1 next { next exch Encoding 3 1 roll put } for
  475. } bind
  476. { 1 next {
  477.     next next 1 add {
  478.             % Stack: gid code
  479.       Encoding 1 index 3 index put
  480.       exch 1 add exch 1 add
  481.     } repeat pop
  482.   } repeat pop
  483. } bind
  484. ] readonly def
  485. /queueEncoding {    % <font> queueEncoding -
  486.   { readEncoding } queueput
  487. } bind def
  488. /readEncoding {        % <data> <font> readEncoding -
  489.   begin 0 () /SubFileDecode filter /f exch store
  490.   /Encoding [ 256 { /.notdef } repeat ] def
  491.   next encodingformats 1 index 127 and get exec
  492.   128 ge {
  493.             % Read supplementary encodings.
  494.     next {
  495.       Encoding next sid idname put
  496.     } repeat
  497.   } if end
  498. } bind def
  499.  
  500. % ------ FDArray and FDSelect ------ %
  501.  
  502. /readFDArray {        % <font> readFDArray -
  503.   /FDarray Index exch pop exch
  504.   2 dict begin /f null def begin
  505.   [ exch {
  506.     dup length subfilefilter /f exch store
  507.     10 dict begin
  508.     /FontType 2 def
  509.     /PaintType 0 def
  510.     /FontMatrix [0.001 0 0 0.001 0 0] def
  511.     /Private 20 dict def
  512.     //topdictops Dict currentdict end
  513.   } forall ] /FDArray xdef end end
  514. } bind def
  515.  
  516. /fdselectformats [
  517. % Note: this procedure can overflow the operand stack.
  518. % We'll fix this if it ever becomes necessary.
  519. { [ exch charstringcount pop { card8 } repeat ] } bind    % Format 0
  520. { /FDSelect cvx /invalidfont signalerror } bind        % Format 1
  521. dup                            % Format 2
  522. % The following procedure does not use excessive op-stack space.
  523. { pop 65535 array card16 card16 exch            % Format 3
  524.   { % Stack: array previndex
  525.     card8 card16 
  526.     exch 1 index 4 -1 roll
  527.     exch 1 exch 1 sub
  528.     { 3 index exch 2 index put } for pop
  529.   } repeat
  530.   % now resize the array to the final index.
  531.   0 exch getinterval
  532. } bind
  533. ] readonly def
  534.  
  535. /readFDSelect {        % <font> readFDSelect -
  536.   begin fdselectformats next get currentdict exch exec /FDSelect exch def end
  537. } bind def
  538.  
  539.  
  540. % ------ Private dictionary ------ %
  541.  
  542. /deltarray {        % -mark- <num1> ... deltarray <num1'> ...
  543.   0 counttomark 1 sub { counttomark -1 roll add dup } repeat pop
  544.   counttomark array astore
  545. } bind def
  546.  
  547. /privatedictops mark
  548.   12 { CFFDEBUG { (\t% EOD) = } if exit }
  549.   6 { deltarray /BlueValues pxdef }
  550.   7 { deltarray /OtherBlues pxdef }
  551.   8 { deltarray /FamilyBlues pxdef }
  552.   9 { deltarray /FamilyOtherBlues pxdef }
  553.   41 { /BlueScale pxdef }
  554.   42 { /BlueShift pxdef }
  555.   43 { /BlueFuzz pxdef }
  556.   10 { 1 array astore /StdHW pxdef }
  557.   11 { 1 array astore /StdVW pxdef }
  558.   44 { deltarray /StemSnapH pxdef }
  559.   45 { deltarray /StemSnapV pxdef }
  560.   46 { 0 ne /ForceBold pxdef }
  561.   47 { /ForceBoldThreshold pxdef }
  562.   48 { /lenIV pxdef }
  563.   49 { /LanguageGroup pxdef }
  564.   50 { /ExpansionFactor pxdef }
  565.   51 { /initialRandomSeed pxdef }
  566.   19 { PrivateStart add { readSubrs } offput }
  567.   20 { /defaultWidthX pxdef }
  568.   21 { /nominalWidthX pxdef }
  569.     % Multiple Master fonts only
  570.   59 { /NDV pxdef }
  571.   60 { /CDV pxdef }
  572.   61 { /lenBuildCharArray pxdef }
  573. .dicttomark readonly def
  574.  
  575. /readPrivate {        % <font> <size> readPrivate -
  576.   2 dict begin
  577.   f 3 1 roll exch       % f <size> <font> 
  578.   StringCache queued_offset known {
  579.     /PrivateStart queued_offset def
  580.   } {
  581.     /PrivateStart pos def
  582.     1 index 0 gt {
  583.       f 2 index string readstring pop
  584.     } {
  585.       ()
  586.     } ifelse
  587.     StringCache queued_offset 2 index put
  588.     0 () /SubFileDecode filter
  589.     /f exch store
  590.   } ifelse
  591.   dup /FontType .knownget not { 2 } if exch
  592.   /Private get begin
  593.         % Default lenIV to -1 even for Type 1 CharStrings.
  594.   2 ne { /lenIV -1 def } if
  595.   //privatedictops Dict end
  596.   exch /f exch store advance
  597.   end
  598. } bind def
  599.  
  600. /readSubrs {        % <font> readSubrs -
  601.   /Subrs Index put
  602. } bind def
  603.  
  604. % ------ Main program ------ %
  605.  
  606. % Clean up after finishing a font.
  607. /cleanupFont {        % (currentdict) cleanupFont -
  608.         % Remove unwanted entries.
  609.   currentdict /charset undef
  610.   currentdict /CharStringArray undef
  611. } bind def
  612.  
  613. % Update the Encoding and CharStrings for a real font.
  614. /finishFont {        % (currentdict) finishFont -
  615.         % Construct the real Encoding.
  616.         % The value of Encoding is either a number, for predefined
  617.         % encodings, or an array of mixed GIDs and names.
  618.   /Encoding mark Encoding
  619.   CFFDEBUG { (Encoding: ) print dup === flush } if
  620.   dup type /integertype eq {
  621.     StandardEncodings exch get { idname } forall
  622.   } {
  623.     {
  624.       dup type /integertype eq { charset exch get idname } if
  625.     } forall
  626.   } ifelse .packtomark def
  627.         % Construct the CharStrings.
  628.         % Note that they may only correspond to an initial
  629.         % subset of the charset.
  630.   /CharStrings charset length CharStringArray length .min dict def
  631.   CFFDEBUG {
  632.     charset length =only ( charset ) print
  633.     CharStringArray length =only ( CharStringArray) =
  634.     charset == flush
  635.   } if
  636.   0 1 CharStrings maxlength 1 sub {
  637.     dup CharStringArray exch get
  638.     exch charset exch get idstring CharStrings xxput
  639.   } for
  640.   cleanupFont
  641. } bind def
  642.  
  643. % Replace CharStrings with GlyphDirectory for a CIDFont;
  644. % Move GlobalSubrs to descendent fonts.
  645. /finishCIDFont {    % (currentdict) finishCIDFont -
  646.         % Construct the GlyphDirectory, similar to CharStrings.
  647.   /FDBytes FDArray length 1 gt { 1 } { 0 } ifelse def
  648.   /GlyphDirectory charset length CharStringArray length .min dict def
  649.   CFFDEBUG {
  650.     charset length =only ( charset ) print
  651.     CharStringArray length =only ( CharStringArray) =
  652.     charset == flush
  653.   } if
  654.   0 1 GlyphDirectory maxlength 1 sub {
  655.     dup CharStringArray exch get
  656.         % If there is more than one FDArray entry, add the font
  657.         % index to the beginning of each charstring.
  658.     FDBytes 1 eq {
  659.       FDSelect 2 index get
  660.       1 string dup 0 4 -1 roll put exch concatstrings
  661.     } if
  662.     exch charset exch get GlyphDirectory xxput
  663.   } for
  664.  
  665.   Private /GlobalSubrs .knownget {
  666.     FDArray {
  667.     /Private get /GlobalSubrs 2 index put
  668.     } forall
  669.     pop
  670.     Private /GlobalSubrs undef
  671.   } if
  672.  
  673.         % Clean up.
  674.   currentdict /FDSelect undef
  675.   cleanupFont
  676. } bind def
  677.  
  678. % PDF may load OpenType font containing ordinary CFF data as a CIDFont.
  679. % Convert the ordinary font to a CIDFont.
  680. /makeCIDFont {        % (currentdict) finishCIDFont -
  681.   /CIDFontType 0 def
  682.   /FDBytes 0 def
  683.   /GDBytes 0 def
  684.   /CIDMapOffset 0 def
  685.  
  686.   /CIDSystemInfo 3 dict begin  % bogus
  687.     /Registry   (Adobe) def
  688.     /Ordering   (Identity) def
  689.     /Supplement 0 def
  690.   currentdict end def
  691.  
  692.   /FDArray 4 dict begin
  693.     /FontMatrix dup load { 1000 0 0 1000 0 0 } matrix concatmatrix def
  694.     /Private    dup load def
  695.     /FontType   dup load def
  696.     /PaintType  dup load def
  697.   currentdict end 1 array astore def
  698.  
  699.   /FontType 9 def
  700.  
  701.   /GlyphDirectory CharStringArray def
  702.   /CIDCount GlyphDirectory length def
  703.  
  704.   currentdict /Private undef
  705.   currentdict /Encoding undef
  706.   currentdict /CharStrings undef
  707.   currentdict /UniqueID undef
  708.   currentdict /XUID undef
  709.   cleanupFont
  710. } bind def
  711.  
  712. % We need to pass the file as a parameter for the sake of the PDF
  713. % interpreter. Also for the sake of PDF, a flag forces the font
  714. % to be defined as <resname> instead of the name embedded in the data.
  715. % This is needed for subsetted fonts; it is valid if the CFF
  716. % contains only a single font.
  717. % Finally, PDF interpreter may request creation of CIDFont out of an
  718. % ordinary CFF font.
  719. /StartData {          % <resname> <nbytes> StartData -
  720.   currentfile exch subfilefilter //false //false ReadData pop
  721. } bind def
  722. /ReadData {           % <resname> <file> <forceresname> <forcecid> ReadData <fontset>
  723.     % Initialize.
  724.  
  725.   30 dict begin
  726.   /forcecidfont exch def
  727.   /forceresname exch def
  728.   /cff exch def
  729.   /pos 0 def
  730.   /resname exch cvlit def
  731.   /DEBUG CFFDEBUG def    % bring the binding closer
  732.   /StringCache 1 dict def % Private DICT may be reused.
  733.  
  734.     % Read the header.
  735.  
  736.   /f cff def
  737.   /vmajor next def
  738.   /vminor next def
  739.   /hdrsize next def
  740.   /aoffsize next def
  741.   hdrsize 4 gt {
  742.     hdrsize 4 sub dup advance
  743.     f exch () /SubFileDecode filter flushfile
  744.   } if
  745.  
  746.     % Read the Indexes.
  747.  
  748.   /names Index def
  749.   /topdicts Index def
  750.   /strings Index def
  751.   /gsubrs Index def
  752.  
  753.     % Read the top Dicts.
  754.  
  755.   /offsets 50 dict def
  756.   /queued [] def
  757.   /opdict null def        % reserve a slot
  758.   /fonts [ topdicts {
  759.     0 () /SubFileDecode filter /f exch def
  760.     40 dict begin
  761.         % Preload defaults that differ from PostScript defaults,
  762.         % or that are required.
  763.       /FontType 2 def
  764.       /PaintType 0 def
  765.       /FontMatrix [0.001 0 0 0.001 0 0] def
  766.       /charset StandardCharsets 0 get def
  767.       /Encoding 0 def
  768.       /FontInfo 10 dict
  769.     dup /UnderlinePosition -100 put
  770.     dup /UnderlineThickness 50 put
  771.       def
  772.       /Private 20 dict
  773.     gsubrs length 0 ne { dup /GlobalSubrs gsubrs put } if
  774.       def
  775.       //topdictops Dict
  776.     currentdict end
  777.   } forall ] def
  778.  
  779.     % Read other tables with queued offsets.
  780.         % We process these in order so we can advance if needed.
  781.     % The CFF file may not be positionable.
  782.   {        % outer loop since offsets may be updated when processing
  783.     CFFDEBUG { (offsets: ) print [ offsets { pop } forall ] == } if
  784.     [ offsets { pop } forall ] { lt } .sort    % process in order of appearance
  785.     { 
  786.       CFFDEBUG { (queued offset: ) print dup =print flush (, current pos=) print pos = } if
  787.       /queued_offset 1 index def
  788.       StringCache 1 index .knownget {
  789.         /f exch 0 () /SubFileDecode filter def
  790.       } {
  791.         /f cff def
  792.         dup pos ne { dup pos sub nextstring pop } if    % negative advance will cause error
  793.       } ifelse
  794.       offsets exch 2 copy get 3 1 roll undef
  795.       CFFDEBUG { (exec queued: ) print dup == } if
  796.       exec
  797.     } forall
  798.     offsets length 0 eq { exit } if
  799.   } loop
  800.  
  801.     % Process out-of-order tables.
  802.  
  803.   CFFDEBUG { queued length =only ( queued) = flush } if
  804.   queued { exec } forall
  805.  
  806.     % Update Encoding and CharStrings.
  807.  
  808.   fonts {
  809.     begin
  810.     currentdict /CIDFontType known {
  811.       finishCIDFont
  812.     } {
  813.       forcecidfont //makeCIDFont //finishFont ifelse
  814.     } ifelse
  815.     end
  816.   } forall
  817.  
  818.     % Wrap up.
  819.  
  820.   resname mark 0 1 fonts length 1 sub {
  821.     CFFDEBUG { dup =only ( ) print flush } if
  822.     dup names exch get
  823.     forceresname { pop resname } if
  824.     CFFDEBUG { dup == flush } if
  825.     exch fonts exch get
  826.     dup /CIDFontType known {
  827.         % This is a CIDFont.
  828.       dup /CIDFontName 3 index put
  829.       1 index exch /CIDFont defineresource
  830.     } {
  831.         % This is a font.
  832.       dup /FontName 3 index put
  833.       1 index exch definefont
  834.     } ifelse
  835.   } for .dicttomark
  836.   end        % temporary dict
  837.   end        % FontSetInit ProcSet
  838.   /FontSet defineresource
  839.  
  840. } bind def
  841.  
  842. % ---------------- Resource category definition ---------------- %
  843.  
  844. currentdict end readonly
  845.  
  846. languagelevel exch 2 .setlanguagelevel
  847.  
  848. /FontSet /Generic /Category findresource dup length dict .copydict
  849. /Category defineresource pop
  850.  
  851. /FontSetInit exch /ProcSet defineresource pop
  852.  
  853. .setlanguagelevel
  854.